package xyz.xtt.schedule.service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.tongtong.share.request.AssistantMessageRequest;

import lombok.extern.slf4j.Slf4j;
import xyz.xtt.common.response.ApiResult;
import xyz.xtt.exchange.client.ExchangeClient;
import xyz.xtt.exchange.dto.TblUserBenefitDto;
import xyz.xtt.exchange.enums.BenefitEnum;

/**
 * @author dale
 * @date 2025/2/12
 **/
@Service
@Slf4j
public class NftVipService {
	private static final String USER_NOTICE_TODAY_CACHE = "vipExpiredUserNoticeToday:%d:%d";
	private static final String USER_NOTICE_IN_3_DAYS_CACHE = "vipExpiredIn3DaysUserNoticeToday:%d:%d";
	private static final String VIP_EXPIRE_MESSAGE = "您的数藏藏会员将于%s到期，为了不影响您的使用，请及时续费";
	@Autowired
	ExchangeClient exchangeClient;
	@Autowired
	InnerService innerService;
	@Autowired
	private StringRedisTemplate redisTemplate;

	public void noticeVipExpire() {
		log.info("noticeVipExpire task start running");
		int pageNo = 1;
		int pageSize = 20;
		List<TblUserBenefitDto> list = null;
		ApiResult<List<TblUserBenefitDto>> result = exchangeClient.getExpiringUserBenefits(pageNo, pageSize, BenefitEnum.NFT_VIP_TAG.getCode());
		if (result.isOk()) {
			list = result.getData();
		}

		while (!CollectionUtils.isEmpty(list)) {
			list.forEach(tblUserBenefitDto -> {
				log.info("noticeVipExpire task start running, uid:{} userBenefitId:{}", tblUserBenefitDto.getAppUserId(), tblUserBenefitDto.getUserBenefitId());
				handleVipExpire(tblUserBenefitDto);
			});
			pageNo++;
			result = exchangeClient.getExpiringUserBenefits(pageNo, pageSize, BenefitEnum.NFT_VIP_TAG.getCode());
			if (result.isOk()) {
				list = result.getData();
			} else {
				list = null;
			}
		}

	}

	private void handleVipExpire(TblUserBenefitDto tblUserBenefitDto) {
		// 查询改用户是否有更新的权益记录，如果有则说明用户已经续费，跳过处理
		ApiResult<TblUserBenefitDto> result = exchangeClient.getLatestUserBenefit(tblUserBenefitDto.getAppUserId() + "", tblUserBenefitDto.getBenefitCode());
		if (result.isOk() && Objects.equals(result.getData().getUserBenefitId(), tblUserBenefitDto.getUserBenefitId())) {
			// 判断是否当前过期
			if (isToday(tblUserBenefitDto.getExpireAt())) {
				// 计算当天 23:59:59 的过期时间
				LocalDateTime now = LocalDateTime.now();
				LocalDateTime endOfDay = now.toLocalDate().atTime(23, 59, 59);
				long secondsUntilEndOfDay = endOfDay.atZone(ZoneId.systemDefault()).toEpochSecond() - now.atZone(ZoneId.systemDefault()).toEpochSecond();
				boolean needNotice = redisTemplate
						.opsForValue()
						.setIfAbsent(String
								.format(USER_NOTICE_TODAY_CACHE, tblUserBenefitDto.getAppUserId(), tblUserBenefitDto
										.getUserBenefitId()), "1", secondsUntilEndOfDay, TimeUnit.SECONDS);
				if (!needNotice) {
					return;
				}
			} else {
				// 计算3天后 23:59:59 的过期时间
				LocalDateTime now = LocalDateTime.now();
				LocalDateTime endOfDay = now.toLocalDate().plusDays(3).atTime(23, 59, 59);
				long secondsUntilEndOfDay = endOfDay.atZone(ZoneId.systemDefault()).toEpochSecond() - now.atZone(ZoneId.systemDefault()).toEpochSecond();
				boolean needNotice = redisTemplate
						.opsForValue()
						.setIfAbsent(String
								.format(USER_NOTICE_IN_3_DAYS_CACHE, tblUserBenefitDto.getAppUserId(), tblUserBenefitDto
										.getUserBenefitId()), "1", secondsUntilEndOfDay, TimeUnit.SECONDS);
				if (!needNotice) {
					return;
				}
			}
			AssistantMessageRequest request = AssistantMessageRequest
					.builder()
					.content(formatNoticeMst(tblUserBenefitDto.getExpireAt()))
					.uid(Arrays.asList(tblUserBenefitDto.getAppUserId()))
					.expiredAtDay(7)
					.build();
			Boolean sendAssistantMsg = innerService.sendAssistantMsg(request);
			log.info("send message sendAssistantMsg:{}", sendAssistantMsg);
		}
	}

	private String formatNoticeMst(LocalDateTime expireAt) {
		return String.format(VIP_EXPIRE_MESSAGE, DateTimeFormatter.ofPattern("yyyy年MM月dd日").format(expireAt));
	}

	/**
	 * 判断给定的 LocalDateTime 是否在当天范围内
	 *
	 * @param dateTime 要检查的 LocalDateTime
	 * @return 如果 dateTime 在当天范围内返回 true，否则返回 false
	 */
	private boolean isToday(LocalDateTime dateTime) {
		if (dateTime == null) {
			return false;
		}
		LocalDate today = LocalDate.now();
		return !dateTime.toLocalDate().isBefore(today) && !dateTime.toLocalDate().isAfter(today);
	}
}
